

(in-package :dreaming-tree)

(defun create-sphere (point-rows points-per-row)
  (let* ((num-vertices (+ 2 (* (- point-rows 2) points-per-row)))
	 (vertices (make-gl-array (* 3 num-vertices) :element-type 'single-float))
	 (colors (make-gl-array (* 3 num-vertices) :element-type 'single-float))
	 (indices '()))
    (flet ((set-x (idx val)
	     (setf (gl-aref vertices (* idx 3)) val))
	   (set-y (idx val)
	     (setf (gl-aref vertices (1+ (* idx 3))) val))
	   (set-z (idx val)
	     (setf (gl-aref vertices (+ 2 (* idx 3))) val))
	   (set-r (idx val)
	     (setf (gl-aref colors (* idx 3)) val))
	   (set-g (idx val)
	     (setf (gl-aref colors (1+ (* idx 3))) val))
	   (set-b (idx val)
	     (setf (gl-aref colors (+ 2 (* idx 3))) val))
	   (idx (i j)
	     (+ (* (1- i) points-per-row) j)))
      (iter (for i from 1 below (1- point-rows))
	    (iter (for j from 0 below points-per-row)
		  (let* ((y  (- 1.0 (* 2.0 (/ i ; y = 1.0 - float(i) / float(PointRows-1)*2.0;
					      (1- points-per-row)))))
			 (r (sin (acos y)))
			 (x (* r (sin (* 2 pi (/ j points-per-row)))))
			 (z (* r (cos (* 2 pi (/ j points-per-row)))))
			 (ij (idx i j)))
		    (set-x ij x)
		    (set-y ij y)
		    (set-z ij z)
		    (set-r ij (/ i point-rows))
		    (set-g ij 0.7)
		    (set-b ij (/ j points-per-row)))))
      (set-x (* (- point-rows 2) points-per-row) 0.0)
      (set-y (* (- point-rows 2) points-per-row) 1.0)
      (set-z (* (- point-rows 2) points-per-row) 0.0)
      (set-r (* (- point-rows 2) points-per-row) 1.0)
      (set-g (* (- point-rows 2) points-per-row) 0.7)
      (set-b (* (- point-rows 2) points-per-row) 1.0)

      (set-x (1+ (* (- point-rows 2) points-per-row)) 0.0)
      (set-y (1+ (* (- point-rows 2) points-per-row)) -1.0)
      (set-z (1+ (* (- point-rows 2) points-per-row)) 0.0)
      (set-r (1+ (* (- point-rows 2) points-per-row)) 1.0)
      (set-g (1+ (* (- point-rows 2) points-per-row)) 0.7)
      (set-b (1+ (* (- point-rows 2) points-per-row)) 1.0)

      (iter (for i from 1 below (- point-rows 2))
	    (iter (for j from 0 below (1- points-per-row))
		  (push (+ (* (1- i) points-per-row) j) indices)
		  (push (+ (* (1- i) points-per-row) j 1) indices)
		  (push (+ (* i points-per-row) j) indices)
		  (push (+ (* (1- i) points-per-row) j 1) indices)
		  (push (+ (* i points-per-row) j 1) indices)
		  (push (+ (* i points-per-row) j) indices))
	    (push (+ (* (1- i) points-per-row) points-per-row -1) indices)
	    (push (* (1- i) points-per-row) indices)
	    (push (+ (* i points-per-row) (- points-per-row 2)) indices)
	    (push (*  i points-per-row) indices)
	    (push (* (1- i) points-per-row) indices)
	    (push (+ (* i points-per-row) (- points-per-row 2)) indices))
	   
      (iter (for j from 0 below (1- points-per-row))
	    (push j indices)
	    (push (1+ j) indices)
	    (push (* (- point-rows 2) points-per-row) indices))
      (push (- points-per-row 2) indices)
      (push 0 indices)
      (push (* (- point-rows 2) points-per-row) indices)

      (iter (for j from 0 below (1- points-per-row))
	    (push (+ j (* (- point-rows 3) points-per-row)) indices)
	    (push (+ j 1 (* (- point-rows 3) points-per-row)) indices)
	    (push (+ 1 (* (- point-rows 2) points-per-row)) indices))
      (push (+ (- points-per-row 2) (* (- point-rows 3) points-per-row)) indices)
      (push (* (- point-rows 3) points-per-row) indices)
      (push (+ 1 (* (- point-rows 3) points-per-row)) indices)

      (let ((index-vector (make-gl-array (length indices) :element-type 'fixnum)))
	(iter (for e in indices)
	      (for i from 0)
	      (setf (gl-aref index-vector i) e))
	(values vertices colors index-vector)))))


(defun draw-sphere (&key indices vcnt (points-only nil))
  (if points-only
      (gldrawarrays GL_POINTS 0 vcnt)
      (gldrawelements GL_TRIANGLES (lib.gl::element-count indices) GL_UNSIGNED_INT (get-pointer indices))))
  
(defparameter *roty* 0.0)

(defun display (vertices colors indices points-p)
  (glClear GL_COLOR_BUFFER_BIT)
  (glLoadIdentity)
  (glTranslatef 0.0 0.0 -4.0)
  (glRotatef *roty* 0.0 1.0 0.0)
  (draw-sphere :indices indices :points-only points-p :vcnt (element-count vertices))
  (sdl-cffi::sdl-gl-swap-buffers))

(defun reshape (x y)
  (unless (and (= y 0) (= x 0))
    (glMatrixMode GL_PROJECTION)
    (glLoadIdentity)
    (#_gluPerspective 40.0d0 (coerce (/ x y) 'double-float) 0.5d0 20.0d0)
    (glViewport 0 0 x y);  //Use the whole window for rendering
    (glMatrixMode GL_MODELVIEW)))

(defun run-vertex-arrays (width height)
  (sdl:with-init ()
    (sdl:window width height
		:flags sdl-cffi::sdl-opengl
		:title-caption "Test Scene"
		:icon-caption "Test Scene")
    (reshape width height)
    (multiple-value-bind (vertices colors indices) (create-sphere 16 16)
      (glPolygonMode GL_FRONT_AND_BACK GL_LINE)
      (glEnableClientState GL_VERTEX_ARRAY)
      (glEnableClientState GL_COLOR_ARRAY)
      (glVertexPointer 3 GL_FLOAT 0 (get-pointer vertices))
      (glColorPointer 3 GL_FLOAT 0 (get-pointer colors))
      (glPointSize 2.0)
      (glClearColor 0.0 0.0 0.0 0.0)
      (setf (sdl:frame-rate) 30)
      (sdl:with-events ()
	(:quit-event () t)
	(:key-down-event (:key key)
			 (if (sdl:key= key :SDL-KEY-ESCAPE)
			     (sdl:push-quit-event)))
	(:idle ()
	       (display vertices colors indices t))))))

(defun draw-loop (v1 v2 v3 v4 v c i)
  (glClear GL_COLOR_BUFFER_BIT)
  (glLoadIdentity)
  (glTranslatef 0.0 -2.0 0.0)
  (glColor3f 1.0 1.0 1.0)
  (glBegin GL_QUADS)
  (glvertex3fv (get-pointer v1))
  (glvertex3fv (get-pointer v2))
  (glvertex3fv (get-pointer v3))
  (glvertex3fv (get-pointer v4))
  (glEnd)
  (glEnableClientState GL_VERTEX_ARRAY)
  (glEnableClientState GL_COLOR_ARRAY)
  (glVertexPointer 3 GL_FLOAT 0 (get-pointer v))
  (glColorPointer 3 GL_FLOAT 0 (get-pointer c))
  (glTranslatef 0.0 4.0 0.0)
  (glDrawElements GL_QUADS (element-count i) GL_UNSIGNED_INT (get-pointer i))
  (glDisableClientState GL_COLOR_ARRAY)
  (glDisableClientState GL_VERTEX_ARRAY))
;  (sdl-cffi::sdl-gl-swap-buffers))

(defun simple-varrays ()
  (sdl:with-init ()
    (sdl:window 640 480
		:flags sdl-cffi::sdl-opengl
		:title-caption "Vertex Arrays"
		:icon-caption "Vertex Arrays")
    (let ((v1 (make-vector 1.0d0 1.0d0 0.0d0))
	  (v2 (make-vector -1.0d0 1.0d0 0.0d0))
	  (v3 (make-vector -1.0d0 -1.0d0 0.0d0))
	  (v4 (make-vector 1.0d0 -1.0d0 0.0d0))
	  (v (make-vector 1.0d0 1.0d0 0.0d0
			  -1.0d0 1.0d0 0.0d0
			  -1.0d0 -1.0d0 0.0d0
			  1.0d0 -1.0d0 0.0d0))
	  (c (make-vector 1.0d0 1.0d0 1.0d0
			  0.5d0 0.5d0 0.5d0
			  1.0d0 1.0d0 1.0d0
			  0.5d0 0.5d0 0.5d0))
	  (i (make-vector 0 1 2 3)))
      (reshape 640 480)
      (glPolygonMode GL_FRONT_AND_BACK GL_LINE)
      (glPointSize 2.0)
      (glClearColor 0.0 0.0 0.0 0.0)
      (setf (sdl:frame-rate) 30)
      (sdl:with-events ()
	(:quit-event () t)
	(:key-down-event (:key key)
			 (if (sdl:key= key :SDL-KEY-ESCAPE)
			     (sdl:push-quit-event)))
	(:idle ()
	       (draw-loop v1 v2 v3 v4 v c i))))))

(defclass simple-varrays (agent-3d-view)
  ())

(defmethod draw ((view simple-varrays))
  (let ((v1 (make-vector 1.0 1.0 0.0))
	(v2 (make-vector -1.0 1.0 0.0))
	(v3 (make-vector -1.0 -1.0 0.0))
	(v4 (make-vector 1.0 -1.0 0.0))
	(v (make-vector 1.0 1.0 0.0
			-1.0 1.0 0.0
			-1.0 -1.0 0.0
			1.0 -1.0 0.0))
	(c (make-vector 1.0 1.0 1.0
			0.5 0.5 0.5
			1.0 1.0 1.0
			0.5 0.5 0.5))
<<<<<<< local
	(i (make-gl-index-array 0 1 2 3)))
=======
	(i (make-vector 0 1 2 3)))
>>>>>>> other
    ;(glPolygonMode GL_FRONT_AND_BACK GL_LINE)
<<<<<<< local
    (glPointSize 2.0)
=======
    ;(glPointSize 2.0)
>>>>>>> other
    (glTranslatef 0.0 -2.0 0.0)
    (glColor3f 1.0 1.0 1.0)
    (glBegin GL_QUADS)
    (glvertex3fv (get-pointer v1))
    (glvertex3fv (get-pointer v2))
    (glvertex3fv (get-pointer v3))
    (glvertex3fv (get-pointer v4))
    (glEnd)
    (glEnableClientState GL_VERTEX_ARRAY)
    (glEnableClientState GL_COLOR_ARRAY)
<<<<<<< local
=======
    (glVertexPointer 3 GL_FLOAT 0 (get-pointer v))
>>>>>>> other
    (glColorPointer 3 GL_FLOAT 0 (get-pointer c))
<<<<<<< local
    (glVertexPointer 3 GL_FLOAT 0 (get-pointer v))
    (glTranslatef 0.0 4.0 0.0)
    ;(gldrawarrays GL_QUADS 0 4)))
    (glDrawElements GL_QUADS (element-count i) GL_UNSIGNED_INT (get-pointer i))))=======
    (glTranslatef 0.0 2.0 0.0)
    (gldrawarrays GL_POINTS 0 4)))
;    (glDrawElements GL_QUADS (element-count i) GL_UNSIGNED_INT (get-pointer i))))>>>>>>> other
